module booth2_16x16_8x8 (
			 output logic [31:0] o_result,
			 input logic [15:0]  i_a, // multiplicand
			 input logic [15:0]  i_b, // multiplier
			 input logic 	     i_sign,
			 input logic 	     i_mode8 // 0:16x16, 1:two 8x8
			 );
   //for 16-bit mode
   wire [15+1:0] 			     a = {i_sign & i_a[15], i_a[15:0]};
   
   wire [15+1:0] 			     a_16 = {i_sign & i_a[15], i_a[15:0]};
   wire [7+1:0] 			     a_8_H = {i_sign & i_a[15], i_a[15:8]};
   wire [7+1:0] 			     a_8_L = {i_sign & i_a[7], i_a[7:0]};
   
   wire [15+2:0] 			     b_16 = {{2{i_sign & i_b[15]}}, i_b[15:0]}; // extend 2 bits for booth2 recoding
   wire [15+3:0] 			     b_16_ext = {b_16, 1'b0};
   wire [7+2:0] 			     b_8_L = {{2{i_sign & i_b[7]}}, i_b[7:0]};
   // wire [7+3:0] 			     b_8_L_ext = {b_8_L, 1'b0};
   // wire [7+2:0] 			     b_8_H = {{2{i_sign & i_b[15]}}, i_b[15:8]};
   // wire [7+3:0] 			     b_8_H_ext = {b_8_H, 1'b0};

   

   
   
   
		 
   logic [15+1:0] 		 pp[8:0]; // total 9 PPs			// FIXME: pp[width/2:0]  // width/2+1
   logic 			 S[8:0];  // the last one is not needed (must be 0)
   logic 			 E[8:0];  // the last one is not needed


   logic [15+1:0] 		 pp_16[8:0]; // PPs for 16-bit mode
   logic [7+1:0] 		 pp_8_H[4:0]; //PPs for 8-bit mode (high 8 bits)
   logic [7+1:0] 		 pp_8_L[4:0];
   logic 			 S_8_H[3:0], S_8_L[3:0];
   logic 			 E_8_H[3:0], E_8_L[3:0];
   
   
   

   
   
   logic [31:0] 		 final_pp0, final_pp1;
   logic [31:0] 		 result; // the real result may be a signed number 


   logic [15:0] 		 result_16b;
   

   wire 			 mode8 = i_mode8;
   

   // ==================== for simulation ====================
   logic signed [2:0] 		 booth_array_sim[8:0]; // 0, +-1, +-2
   logic signed [15+1:0] 	 pp_sim[8:0];
   logic 			 S_sim[8:0];
   logic 			 E_sim[8:0];
   logic [3:0] 			 cols_sim[31:0]; // the max column height is 9, so must use 4 bits to represent
   
   logic [3:0] 			 cols_sim_H[31:0];
   
   

   //logic signed [15+1:0] 	 pp_actual[8:0];
   logic signed [31:0] 		 pp_actual_sim[8:0]; // 17 bits or 32bits ????
   
      

   //wire [15+1:0] 		 a_mix;
   wire [15+1:0] 		 a_mix_16 = a[16:0];
   wire [15+1:0] 		 a_mix_8_H = {a[16:8], 1'b0, a[6:0]}; // only one bit are diff with a_mix_16
   wire [15+1:0] 		 a_mix_8_L = {a[16:9], a[7], a[7:0]};

   wire [15+1:0] 		 a_mix_0 = mode8 ? a_mix_8_L : a_mix_16;
   wire [15+1:0] 		 a_mix_1 = mode8 ? a_mix_8_H : a_mix_16;
   
   wire 				 a_sign_mix_0 = mode8 ? a_8_L[8] : a_mix_16[16];
   wire 				 a_sign_mix_1 = mode8 ? a_8_H[8] : a_mix_16[16];

   // for mixed mode
   booth2_pp_gen_mix #(16+1) mul_pp0
     (
      .pp_out(pp[0]),
      .pp_s(S[0]),
      .pp_e(E[0]),
      
      .mcand_sign(a_sign_mix_0),          // the sign bit
      .mcand(a_mix_0[15:0]),				// multiplicand, do not give the sign bit here
      .booth2(b_16_ext[2:0])
      );


   booth2_pp_gen_mix #(16+1) mul_pp1
     (
      .pp_out(pp[1]),
      .pp_s(S[1]),
      .pp_e(E[1]),
      
      .mcand_sign(a_sign_mix_0),          // the sign bit
      .mcand(a_mix_0[15:0]),				// multiplicand, do not give the sign bit here
      .booth2(b_16_ext[4:2])
      );


   booth2_pp_gen_mix #(16+1) mul_pp2
     (
      .pp_out(pp[2]),
      .pp_s(S[2]),
      .pp_e(E[2]),
      
      .mcand_sign(a_sign_mix_0),          // the sign bit
      .mcand(a_mix_0[15:0]),				// multiplicand, do not give the sign bit here
      .booth2(b_16_ext[6:4])
      );


   booth2_pp_gen_mix #(16+1) mul_pp3
     (
      .pp_out(pp[3]),
      .pp_s(S[3]),
      .pp_e(E[3]),
      
      .mcand_sign(a_sign_mix_0),          // the sign bit
      .mcand(a_mix_0[15:0]),				// multiplicand, do not give the sign bit here
      .booth2(b_16_ext[8:6])
      );


   booth2_pp_gen_mix #(16+1) mul_pp4
     (
      .pp_out(pp[4]),
      .pp_s(S[4]),
      .pp_e(E[4]),
      
      .mcand_sign(a_sign_mix_0),          // the sign bit
      .mcand(a_mix_0[15:0]),				// multiplicand, do not give the sign bit here
      .booth2(b_16_ext[10:8])
      );


   booth2_pp_gen_mix #(16+1) mul_pp5
     (
      .pp_out(pp[5]),
      .pp_s(S[5]),
      .pp_e(E[5]),
      
      .mcand_sign(a_sign_mix_1),          // the sign bit
      .mcand(a_mix_1[15:0]),				// multiplicand, do not give the sign bit here
      .booth2(b_16_ext[12:10])
      );


   booth2_pp_gen_mix #(16+1) mul_pp6
     (
      .pp_out(pp[6]),
      .pp_s(S[6]),
      .pp_e(E[6]),
      
      .mcand_sign(a_sign_mix_1),          // the sign bit
      .mcand(a_mix_1[15:0]),				// multiplicand, do not give the sign bit here
      .booth2(b_16_ext[14:12])
      );


   booth2_pp_gen_mix #(16+1) mul_pp7
     (
      .pp_out(pp[7]),
      .pp_s(S[7]),
      .pp_e(E[7]),
      
      .mcand_sign(a_sign_mix_1),          // the sign bit
      .mcand(a_mix_1[15:0]),				// multiplicand, do not give the sign bit here
      .booth2(b_16_ext[16:14])
      );


   booth2_pp_gen_mix #(16+1) mul_pp8
     (
      .pp_out(pp[8]),
      .pp_s(S[8]),
      .pp_e(E[8]),
      
      .mcand_sign(a_sign_mix_1),          // the sign bit
      .mcand(a_mix_1[15:0]),				// multiplicand, do not give the sign bit here
      .booth2(b_16_ext[18:16])
      );


   

   assign pp_8_L[0] = pp[0][8:0];	// low 9 bits from pp_common
   assign pp_8_L[1] = pp[1][8:0];
   assign pp_8_L[2] = pp[2][8:0];
   assign pp_8_L[3] = pp[3][8:0];
   
   booth2_pp_gen_mix #(8+1) mul_pp8_L
     (
      .pp_out(pp_8_L[4]),
      .pp_s(),
      .pp_e(),

	  .mcand_sign(a_8_L[8]), 
      .mcand(a_8_L[7:0]),				// multiplicand
      .booth2({{2{i_sign & b_16_ext[8]}}, b_16_ext[8]})
      );

   //the S for pp_8_L
   //S[0], S[1], S[2], S[3]
   assign S_8_L[0] = S[0];
   assign S_8_L[1] = S[1];
   assign S_8_L[2] = S[2];
   assign S_8_L[3] = S[3];
   
   //the E for pp_8_L
   //E[0], E[1], E[2], E[3]
   assign E_8_L[0] = E[0];
   assign E_8_L[1] = E[1];
   assign E_8_L[2] = E[2];
   assign E_8_L[3] = E[3];
   

   
   

   assign pp_8_H[1] = pp[5][16:8];	// high 9 bits from pp_common
   assign pp_8_H[2] = pp[6][16:8];
   assign pp_8_H[3] = pp[7][16:8];
   assign pp_8_H[4] = pp[8][16:8];

   booth2_pp_gen_mix #(8+1) mul_pp8_H
     (
      .pp_out(pp_8_H[0]),
      .pp_s(S_8_H[0]),
      .pp_e(E_8_H[0]),

      .mcand_sign(a_8_H[8]),
      .mcand(a_8_H[7:0]),				// multiplicand
      .booth2({b_16_ext[10:9], 1'b0})
      );

   //S[0], S[1], S[2], S[3]
   assign S_8_H[1] = S[5];
   assign S_8_H[2] = S[6];
   assign S_8_H[3] = S[7];
   
   //the E for pp_8_L
   assign E_8_H[1] = E[5];
   assign E_8_H[2] = E[6];
   assign E_8_H[3] = E[7];
   
   
   // // for 16-bit mode
   // // ========== generate PPs and sign compensation : S, E ==========
   // generate
   //    genvar 			 i;
   //    for(i=0;i<9;i++)
   // 	begin : mul_pps
   // 	   booth2_pp_gen #(16+1) unit // mul_pps[1].unit.xxx, the width of PP should one more than the input width
   // 	    (
   // 	     .pp_out(pp[i]),
   // 	     .pp_s(S[i]),
   // 	     .pp_e(E[i]),

   // 	     .mcand(a_mix),				// multiplicand
   // 	     .booth2(b_16_ext[i*2+2:i*2])	// booth2 code of multiplier
   // 	     );
   // 	end // block: mul_pp
   // endgenerate

   // only for 8-bit mode
   


// ==================== compress ====================

   
   
   // ==================== the final CPA ====================
   assign o_result = final_pp0 + final_pp1;
   
   
   

   logic signed [31:0] correct_result;
   logic signed [31:0] tmp_result;

   bit 		       flag;
   initial begin
      #10
	// $display("========== multiply : %d * %d", $signed(a_16), $signed(b_16));
	$display("========== multiply : %d * %d", $signed(a_8_L), $signed(b_8_L));
      

      // ==================== for simulation ====================
      //booth2 recoding 
      for(int i=0;i<=16;i+=2)	// total 9
	begin
	   booth_array_sim[i/2] = b_16_ext[i] + b_16_ext[i+1] - 2*b_16_ext[i+2]; // 0,+-1,+-2
	   $display("booth_array[%d] = %d", i/2, booth_array_sim[i/2]);
	end
      //gen actual value of PPs for verify
      for(int i=0;i<=8;i++)
	begin
	   pp_actual_sim[i] = $signed(a_16) * booth_array_sim[i];
	   $display("actual PP[%d] = %d(%x)", i, pp_actual_sim[i], pp_actual_sim[i]);
	end
      tmp_result = 0;
      for(int i=0;i<=8;i++)
	tmp_result += pp_actual_sim[i]<<(i*2); // remember the shift
      $display("========== the sum of actual PPs is %d(%x)", tmp_result, tmp_result);
      
      // gen PPs and S, E
      for(int i=0;i<=8;i++)
	begin
	   case(booth_array_sim[i])
	     3'd0:
	       begin
		  pp_sim[i] = '0;
	       end
	     3'd1:
	       pp_sim[i] = a_16;
	     3'd2:
	       pp_sim[i] = a_16<<1;
	     -3'd1:
	       pp_sim[i] = ~a_16;
	     -3'd2:
	       pp_sim[i] = ~(a_16<<1);
	   endcase // case (booth_array_sim[i])
	   //S (the same as the sign of booth_array_sim[i])
	   if(booth_array_sim[i] < 0)
	     S_sim[i] = 1'b1;
	   else
	     S_sim[i] = 1'b0;
	   //E
	   E_sim[i] = (booth_array_sim[i] == 3'd0) ? 1'b1 : S_sim[i] ~^ a_16[16];
	end // for (int i=0;i<=8;i++)


      flag = 1;
      $display("check the correctness of all PPs");
      for(int i=0;i<=8;i++)
	begin
	   flag &= (pp[i] == pp_sim[i]);
	   $display("pp[%d]=%x\tpp_sim[%d]=%x  => %s", i, pp[i], i, pp_sim[i], pp[i]==pp_sim[i] ? "equal" : "!!! not equal !!!");
	end
      if(flag)
	$display("========== all PPs are correct");
      else
	$display("*E: some PPs are error !");

      flag = 1;
      for(int i=0;i<=8;i++)
	begin
	   flag &= (S[i] == S_sim[i]);
	   $display("S[%d]=%d\tS_sim[%d]=%d  => %s", i, S[i], i, S_sim[i], S[i]==S_sim[i] ? "equal" : "!!! not equal !!!");
	end
      if(flag)
	$display("========== all S are correct");
      else
	$display("*E: some S are error !");

      flag = 1;
      for(int i=0;i<=8;i++)
	begin
	   flag &= (E[i] == E_sim[i]);
	   $display("E[%d]=%d\tE_sim[%d]=%d  => %s", i, E[i], i, E_sim[i], E[i]==E_sim[i] ? "equal" : "!!! not equal !!!");
	end
      if(flag)
	$display("========== all E are correct");
      else
	$display("*E: some E are error !");




      for(int i=0;i<=4;i++)
	$display("pp_8_L[%d] = 0x%x", i, pp_8_L[i]);

      for(int i=0;i<4;i++)
	$display("S_8_L[%d] = %d, E_8_L[%d] = %d", i, S_8_L[i], i, E_8_L[i]);
	  
	  
      cols_sim[0] = pp_8_L[0][0] + S_8_L[0];
      cols_sim[1] = pp_8_L[0][1];
      cols_sim[2] = pp_8_L[0][2] + pp_8_L[1][0] + S_8_L[1];
      cols_sim[3] = pp_8_L[0][3] + pp_8_L[1][1];
      cols_sim[4] = pp_8_L[0][4] + pp_8_L[1][2] + pp_8_L[2][0] + S_8_L[2];
      cols_sim[5] = pp_8_L[0][5] + pp_8_L[1][3] + pp_8_L[2][1];
      cols_sim[6] = pp_8_L[0][6] + pp_8_L[1][4] + pp_8_L[2][2] + pp_8_L[3][0] + S_8_L[3];
      cols_sim[7] = pp_8_L[0][7] + pp_8_L[1][5] + pp_8_L[2][3] + pp_8_L[3][1];
      cols_sim[8] = pp_8_L[0][8] + pp_8_L[1][6] + pp_8_L[2][4] + pp_8_L[3][2] + pp_8_L[4][0];
      cols_sim[9] = {~E_8_L[0]} + pp_8_L[1][7] + pp_8_L[2][5] + pp_8_L[3][3] + pp_8_L[4][1];
      cols_sim[10] = {~E_8_L[0]} + pp_8_L[1][8] + pp_8_L[2][6] + pp_8_L[3][4] + pp_8_L[4][2];
      cols_sim[11] = E_8_L[0] + E_8_L[1] + pp_8_L[2][7] + pp_8_L[3][5] + pp_8_L[4][3];
      cols_sim[12] = 1'b1 + pp_8_L[2][8] + pp_8_L[3][6] + pp_8_L[4][4];
      cols_sim[13] = E_8_L[2] + pp_8_L[3][7] + pp_8_L[4][5];
      cols_sim[14] = 1'b1 + pp_8_L[3][8] + pp_8_L[4][6];
      cols_sim[15] = E_8_L[3] + pp_8_L[4][7];


      // result_16b = 0;
      // for(int i=0;i<=15;i++)
	  // 	begin
	  // 	   result_16b += cols_sim[i]<<i;
	  // 	end
      // $display("after compress(8-bit mode) result = %d (%x)", $signed(result_16b), result_16b);

      //calc the 8x8 result when in 32 mode
      for(int i=16;i<32;i++)
      	cols_sim[i] = 1;		// must add a 11...11,00...00 (16 ones in the high 16 bits)
      result = 0;
      for(int i=0;i<32;i++)
      	result += cols_sim[i]<<i;
      $display("after compress(8-bit mode, low 8 bits) result = %d (%x)", $signed(result), result);



	
	


      for(int i=0;i<=4;i++)
	$display("pp_8_H[%d] = 0x%x", i, pp_8_H[i]);

      for(int i=0;i<4;i++)
	$display("S_8_H[%d] = %d, E_8_H[%d] = %d", i, S_8_H[i], i, E_8_H[i]);

      
      for(int i=0;i<=15;i++)
	cols_sim_H[i] = 0;
      cols_sim_H[16] = pp_8_H[0][0] + S_8_H[0];
      cols_sim_H[17] = pp_8_H[0][1];
      cols_sim_H[18] = pp_8_H[0][2] + pp_8_H[1][0] + S_8_H[1];
      cols_sim_H[19] = pp_8_H[0][3] + pp_8_H[1][1];
      cols_sim_H[20] = pp_8_H[0][4] + pp_8_H[1][2] + pp_8_H[2][0] + S_8_H[2];
      cols_sim_H[21] = pp_8_H[0][5] + pp_8_H[1][3] + pp_8_H[2][1];
      cols_sim_H[22] = pp_8_H[0][6] + pp_8_H[1][4] + pp_8_H[2][2] + pp_8_H[3][0] + S_8_H[3];
      cols_sim_H[23] = pp_8_H[0][7] + pp_8_H[1][5] + pp_8_H[2][3] + pp_8_H[3][1];
      cols_sim_H[24] = pp_8_H[0][8] + pp_8_H[1][6] + pp_8_H[2][4] + pp_8_H[3][2] + pp_8_H[4][0];
      cols_sim_H[25] = {~E_8_H[0]} + pp_8_H[1][7] + pp_8_H[2][5] + pp_8_H[3][3] + pp_8_H[4][1];
      cols_sim_H[26] = {~E_8_H[0]} + pp_8_H[1][8] + pp_8_H[2][6] + pp_8_H[3][4] + pp_8_H[4][2];
      cols_sim_H[27] = E_8_H[0] + E_8_H[1] + pp_8_H[2][7] + pp_8_H[3][5] + pp_8_H[4][3];
      cols_sim_H[28] = 1'b1 + pp_8_H[2][8] + pp_8_H[3][6] + pp_8_H[4][4];
      cols_sim_H[29] = E_8_H[2] + pp_8_H[3][7] + pp_8_H[4][5];
      cols_sim_H[30] = 1'b1 + pp_8_H[3][8] + pp_8_H[4][6];
      cols_sim_H[31] = E_8_H[3] + pp_8_H[4][7];

      result = 0;
      for(int i=0;i<32;i++)
	result += cols_sim_H[i]<<i;
      $display("after compress(8-bit mode, high 8 bits) result = %d (%x)", $signed(result[31:16]), result);




      $display("calc the two 8x8 result simultaneously");
      for(int i=16;i<32;i++)
	cols_sim[i] = cols_sim_H[i] + 1;
      result = 0;
      for(int i=0;i<32;i++)
	result += cols_sim[i]<<i;
      $display("after compress simultaneously, result = %d (%x)", $signed(result), result);
      
      

      
      // $display("a_sign_mix_0 = %d", a_sign_mix_0);
      // $display("a_mix_0[15:0] = %x", a_mix_0[15:0]);
      // $display("b_16_ext[4:2] = %x", b_16_ext[4:2]);
      // $display("pp[1] = %x", pp[1]);
      // $display("S[1] = %d", S[1]);
      // $display("E[1] = %d", E[1]);
	  
      $finish;
      
      




      
      // add each column
      cols_sim[0] = pp_sim[0][0] + S_sim[0];
      cols_sim[1] = pp_sim[0][1];
      cols_sim[2] = pp_sim[0][2] + pp_sim[1][0] + S_sim[1];
      cols_sim[3] = pp_sim[0][3] + pp_sim[1][1];
      cols_sim[4] = pp_sim[0][4] + pp_sim[1][2] + pp_sim[2][0] + S_sim[2];
      cols_sim[5] = pp_sim[0][5] + pp_sim[1][3] + pp_sim[2][1];
      cols_sim[6] = pp_sim[0][6] + pp_sim[1][4] + pp_sim[2][2] + pp_sim[3][0] + S_sim[3];
      cols_sim[7] = pp_sim[0][7] + pp_sim[1][5] + pp_sim[2][3] + pp_sim[3][1];
      cols_sim[8] = pp_sim[0][8] + pp_sim[1][6] + pp_sim[2][4] + pp_sim[3][2] + pp_sim[4][0] + S_sim[4];
      cols_sim[9] = pp_sim[0][9] + pp_sim[1][7] + pp_sim[2][5] + pp_sim[3][3] + pp_sim[4][1];
      cols_sim[10] = pp_sim[0][10] + pp_sim[1][8] + pp_sim[2][6] + pp_sim[3][4] + pp_sim[4][2] + pp_sim[5][0] + S_sim[5];
      cols_sim[11] = pp_sim[0][11] + pp_sim[1][9] + pp_sim[2][7] + pp_sim[3][5] + pp_sim[4][3] + pp_sim[5][1];
      cols_sim[12] = pp_sim[0][12] + pp_sim[1][10] + pp_sim[2][8] + pp_sim[3][6] + pp_sim[4][4] + pp_sim[5][2] + pp_sim[6][0] + S_sim[6];
      cols_sim[13] = pp_sim[0][13] + pp_sim[1][11] + pp_sim[2][9] + pp_sim[3][7] + pp_sim[4][5] + pp_sim[5][3] + pp_sim[6][1];
      cols_sim[14] = pp_sim[0][14] + pp_sim[1][12] + pp_sim[2][10] + pp_sim[3][8] + pp_sim[4][6] + pp_sim[5][4] + pp_sim[6][2] + pp_sim[7][0] + S_sim[7];
      cols_sim[15] = pp_sim[0][15] + pp_sim[1][13] + pp_sim[2][11] + pp_sim[3][9] + pp_sim[4][7] + pp_sim[5][5] + pp_sim[6][3] + pp_sim[7][1];
      cols_sim[16] = pp_sim[0][16] + pp_sim[1][14] + pp_sim[2][12] + pp_sim[3][10] + pp_sim[4][8] + pp_sim[5][6] + pp_sim[6][4] + pp_sim[7][2] + pp_sim[8][0];
      cols_sim[17] = {~E_sim[0]} + pp_sim[1][15] + pp_sim[2][13] + pp_sim[3][11] + pp_sim[4][9] + pp_sim[5][7] + pp_sim[6][5] + pp_sim[7][3] + pp_sim[8][1];
      cols_sim[18] = {~E_sim[0]} + pp_sim[1][16] + pp_sim[2][14] + pp_sim[3][12] + pp_sim[4][10] + pp_sim[5][8] + pp_sim[6][6] + pp_sim[7][4] + pp_sim[8][2];
      cols_sim[19] = E_sim[0] + E_sim[1] + pp_sim[2][15] + pp_sim[3][13] + pp_sim[4][11] + pp_sim[5][9] + pp_sim[6][7] + pp_sim[7][5] + pp_sim[8][3];
      cols_sim[20] = 1 + pp_sim[2][16] + pp_sim[3][14] + pp_sim[4][12] + pp_sim[5][10] + pp_sim[6][8] + pp_sim[7][6] + pp_sim[8][4];
      cols_sim[21] = E_sim[2] + pp_sim[3][15] + pp_sim[4][13] + pp_sim[5][11] + pp_sim[6][9] + pp_sim[7][7] + pp_sim[8][5];
      cols_sim[22] = 1 + pp_sim[3][16] + pp_sim[4][14] + pp_sim[5][12] + pp_sim[6][10] + pp_sim[7][8] + pp_sim[8][6];
      cols_sim[23] = E_sim[3] + pp_sim[4][15] + pp_sim[5][13] + pp_sim[6][11] + pp_sim[7][9] + pp_sim[8][7];
      cols_sim[24] = 1 + pp_sim[4][16] + pp_sim[5][14] + pp_sim[6][12] + pp_sim[7][10] + pp_sim[8][8];
      cols_sim[25] = E_sim[4] + pp_sim[5][15] + pp_sim[6][13] + pp_sim[7][11] + pp_sim[8][9];
      cols_sim[26] = 1 + pp_sim[5][16] + pp_sim[6][14] + pp_sim[7][12] + pp_sim[8][10];
      cols_sim[27] = E_sim[5] + pp_sim[6][15] + pp_sim[7][13] + pp_sim[8][11];
      cols_sim[28] = 1 + pp_sim[6][16] + pp_sim[7][14] + pp_sim[8][12];
      cols_sim[29] = E_sim[6] + pp_sim[7][15] + pp_sim[8][13];
      cols_sim[30] = 1 + pp_sim[7][16] + pp_sim[8][14];
      cols_sim[31] = E_sim[7] + pp_sim[8][15];
      
      for(int i=0;i<=31;i++)
	$display("cols_sim[%d] = %d", i, cols_sim[i]);
      
      result = 0;
      for(int i=0;i<=31;i++)
	begin
	   result += cols_sim[i]<<i;
	end
      $display("after compress result = %d (%x)", $signed(result), result);
      

      result = 0;
      result += final_pp0;
      result += final_pp1;
      $display("after wallace compress, result = %d (%x)", $signed(result), result);
      
  
      // #20
      // 	$display("a*b = %d * %d", $signed(a_16), $signed(b_16));
      // result = 0;
	  // for(int i=0;i<9;i++)
      // 	begin
	  // 	   result += pp[i]<<(i*2); // must add the S and E ???
	  // 	   $display("pp[%d] = %x, S[%d] = %d, E[%d] = %d", i, pp[i], i, S[i], i, E[i]);
	  // 	end
	  // $display("result : %x(%d)", result, $signed(result));

	  // correct_result = $signed(a_16)*$signed(b_16);
	  // $display("correct result : %x(%d)", correct_result, correct_result);
	  // if(result == correct_result)
	  // 	$display("========== result correct ==========");
	  // else
	  // 	$display("========== result error ==========");
   end
   

endmodule // booth2_16x16_8x8
